package com.cdplife.ci.modular.system.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.cdplife.ci.core.common.constant.AuthDimensionEnum;
import com.cdplife.ci.core.common.node.ZTreeNode;
import com.cdplife.ci.modular.system.dao.AuthRelationMapper;
import com.cdplife.ci.modular.system.dao.InsuranceMapper;
import com.cdplife.ci.modular.system.dao.TenantMapper;
import com.cdplife.ci.modular.system.model.AuthRelation;
import com.cdplife.ci.modular.system.service.IAuthRelationService;

import cn.hutool.core.convert.Convert;
import cn.stylefeng.roses.core.util.ToolUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * 角色数据权限关系
 * @author Shilin.Qu
 *
 */
@Service
public class AuthRelationServiceImpl extends ServiceImpl<AuthRelationMapper, AuthRelation> implements IAuthRelationService {
	
	@Resource
	private AuthRelationMapper authRelationMapper;
	@Resource
	private InsuranceMapper insuranceMapper;
	@Resource
	private TenantMapper tenantMapper;
	 
	/**
	 * 区分保险公司，客户，员工方案分组，在三组数据的id前面分别加上2,3,4   父级为1   
	 * 1,2,3,4都为prefix，在AuthDimensionEnum中定义
	 * 后续添加需继续扩展
	 */
	@Override
	@Transactional
	public List<ZTreeNode> authTreeList(Integer roleId) {
		// 1. 获取定义的数据权限维度
		List<Map<String,Object>> dimensionList = this.authRelationMapper.selectDimension();
		
		Map<Integer,List<Long>> existAuthList = getDimensionAuthority(roleId);
		
		List<ZTreeNode> resultList = new ArrayList<ZTreeNode>();
		for(Map<String,Object> dimension : dimensionList) {
			
			String config_key = (String)dimension.get("config_key");
			
			ZTreeNode zNode = new ZTreeNode();
			zNode.setId(convertToLongParam(AuthDimensionEnum.PARENT.getPrefix(),(Long)dimension.get("id")));
			zNode.setIsOpen(false);
			boolean checked = false;
			if(!ToolUtil.isEmpty(existAuthList.get(AuthDimensionEnum.PARENT.getPrefix()))) {
				checked = existAuthList.get(AuthDimensionEnum.PARENT.getPrefix()).contains((Long)dimension.get("id"));
			}
			zNode.setChecked(checked);
			zNode.setName((String)dimension.get("config_value"));
			zNode.setpId(0L);
			resultList.add(zNode);
			
			// 保险公司
			if(config_key.equals(AuthDimensionEnum.INSURANCE.getCode())) {
						
				List<Map<String, Object>> insuranceList = this.insuranceMapper.selectInsurance(null);
				for(Map<String,Object> insurance : insuranceList) {
					ZTreeNode cNode = new ZTreeNode();
					cNode.setId(convertToLongParam(AuthDimensionEnum.INSURANCE.getPrefix(),(Long)insurance.get("id")));
					cNode.setIsOpen(false);
					boolean checked1 = false;
					if(!ToolUtil.isEmpty(existAuthList.get(AuthDimensionEnum.INSURANCE.getPrefix()))) {
						checked1 = existAuthList.get(AuthDimensionEnum.INSURANCE.getPrefix()).contains((Long)insurance.get("id"));
					}
					cNode.setChecked(checked1);
					cNode.setName((String)insurance.get("insuranceName"));
					cNode.setpId(convertToLongParam(AuthDimensionEnum.PARENT.getPrefix(),(Long)dimension.get("id")));
					resultList.add(cNode);
				}
			}
			
			// 客户
			if(config_key.equals(AuthDimensionEnum.TENANT.getCode())) {
				List<Map<String, Object>> tenantList = this.tenantMapper.selectTenantList(null);
				for(Map<String,Object> tenant : tenantList) {
					ZTreeNode cNode = new ZTreeNode();
					cNode.setId(convertToLongParam(AuthDimensionEnum.TENANT.getPrefix(),(Long)tenant.get("id")));
					cNode.setIsOpen(false);
					boolean checked1 = false;
					if(!ToolUtil.isEmpty(existAuthList.get(AuthDimensionEnum.TENANT.getPrefix()))) {
						checked1 = existAuthList.get(AuthDimensionEnum.TENANT.getPrefix()).contains((Long)tenant.get("id"));
					}
					cNode.setChecked(checked1);
					cNode.setName((String)tenant.get("tenantName"));
					cNode.setpId(convertToLongParam(AuthDimensionEnum.PARENT.getPrefix(),(Long)dimension.get("id")));
					resultList.add(cNode);
				}
			}
			
			// 员工方案分组
			if(config_key.equals(AuthDimensionEnum.EMPLOYEE_GROUP.getCode())) {
				
			}		
		}
		return resultList;
	}

	/**
	 * 保存角色与数据权限的关系
	 */
	@Override
	@Transactional
	public boolean setDimensionAuthority(Integer roleId, String ids) {
		// 1.删除老数据
		this.authRelationMapper.deleteAuthRelationByRoleId(roleId);
		// 2.添加新数据
		List<AuthRelation> arList = new ArrayList<>();
		Map<Integer,String> valueMap = new HashMap<>();
		for (String id : ids.split(",")) {
           if(id == "0") continue;
           
           int prefix = Integer.parseInt(id.substring(0,1));
           
           if(prefix == AuthDimensionEnum.PARENT.getPrefix()) {
        	   AuthRelation ar = new AuthRelation();
               ar.setRoleId(roleId);
               ar.setAuthId(Long.parseLong(id.substring(1,id.length())));
               arList.add(ar);
           }
           
           if(prefix == AuthDimensionEnum.INSURANCE.getPrefix() || prefix == AuthDimensionEnum.TENANT.getPrefix() || prefix == AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix()) {
        	   String value = valueMap.get(prefix);
               
               if(value != null) {
            	   valueMap.put(prefix, value + "," + id.substring(1,id.length()));
               }else {
            	   valueMap.put(prefix, id.substring(1,id.length()));
               }
           }
        }
		
		for (AuthRelation ar : arList) {
			if(ar.getAuthId() == AuthDimensionEnum.INSURANCE.getId()) {
				ar.setValue(valueMap.get(AuthDimensionEnum.INSURANCE.getPrefix()));
			}
			if(ar.getAuthId() == AuthDimensionEnum.TENANT.getId()) {
				ar.setValue(valueMap.get(AuthDimensionEnum.TENANT.getPrefix()));
			}
			if(ar.getAuthId() == AuthDimensionEnum.EMPLOYEE_GROUP.getId()) {
				ar.setValue(valueMap.get(AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix()));
			}
			this.authRelationMapper.insert(ar);
		}
		return true;
	}

	/**
	 * 获取角色与数据权限关系数据，回显页面
	 * @param roleId
	 * @return
	 */
	public Map<Integer,List<Long>> getDimensionAuthority(Integer roleId) {
		
		Map<String,Object> columnMap = new HashMap<>();
		columnMap.put("role_id", roleId);
		List<AuthRelation> authRelationList= this.authRelationMapper.selectByMap(columnMap);
		
		Map<Integer,List<Long>> resultMap = new HashMap<>();
		
		List<Long> parentList = new ArrayList<>();
		for(AuthRelation authRelation : authRelationList) {
			parentList.add(authRelation.getAuthId());
			
			Long[] values = {};
			if(!ToolUtil.isEmpty(authRelation.getValue())) {
				values = Convert.toLongArray(authRelation.getValue().split(","));
			}
			
			if(authRelation.getAuthId() == AuthDimensionEnum.INSURANCE.getId()) {
				resultMap.put(AuthDimensionEnum.INSURANCE.getPrefix(), Arrays.asList(values));
			}
			
			if(authRelation.getAuthId() == AuthDimensionEnum.TENANT.getId()) {
				resultMap.put(AuthDimensionEnum.TENANT.getPrefix(), Arrays.asList(values));
			}
			
			if(authRelation.getAuthId() == AuthDimensionEnum.EMPLOYEE_GROUP.getId()) {
				resultMap.put(AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix(), Arrays.asList(values));
			}
			
		}		
		resultMap.put(AuthDimensionEnum.PARENT.getPrefix(), parentList);
		
		return resultMap;
	}
	
	/**
	 * 获取一堆角色对应的数据权限（取最大集合）
	 * @param roleList
	 * @return
	 */
	public Map<Integer,List<Long>> getMaxDimensionAuthority(List<Integer> roleList) {
		Map<Integer,List<Long>> resultMap = new HashMap<>();
		
		List<AuthRelation> authRelationList = this.authRelationMapper.selectAuthRelationListByRoleIds(roleList);
		List<Long> parentList = new ArrayList<>();
		for(AuthRelation authRelation : authRelationList) {
			if(!parentList.contains(authRelation.getAuthId())) {
				parentList.add(authRelation.getAuthId());
			}
			
			Long[] values = {};
			if(!ToolUtil.isEmpty(authRelation.getValue())) {
				values = Convert.toLongArray(authRelation.getValue().split(","));
			}
			
			if(authRelation.getAuthId() == AuthDimensionEnum.INSURANCE.getId()) {
				if(resultMap.get(AuthDimensionEnum.INSURANCE.getPrefix()) == null) {
					resultMap.put(AuthDimensionEnum.INSURANCE.getPrefix(), new ArrayList<Long>(Arrays.asList(values)));
				}else {
					List<Long> sourceList = resultMap.get(AuthDimensionEnum.INSURANCE.getPrefix());
					sourceList.addAll(new ArrayList<Long>(Arrays.asList(values)));
					// 利用set去重
					Set<Long> set = new HashSet<>(sourceList);
			        List<Long> destList = new ArrayList<>(set);
			        resultMap.put(AuthDimensionEnum.INSURANCE.getPrefix(), destList);
				}	
			}
			
			if(authRelation.getAuthId() == AuthDimensionEnum.TENANT.getId()) {
				if(resultMap.get(AuthDimensionEnum.TENANT.getPrefix()) == null) {
					resultMap.put(AuthDimensionEnum.TENANT.getPrefix(), new ArrayList<Long>(Arrays.asList(values)));
				}else {
					List<Long> sourceList = resultMap.get(AuthDimensionEnum.TENANT.getPrefix());
					sourceList.addAll(new ArrayList<Long>(Arrays.asList(values)));
					// 利用set去重
					Set<Long> set = new HashSet<>(sourceList);
			        List<Long> destList = new ArrayList<>(set);
			        resultMap.put(AuthDimensionEnum.TENANT.getPrefix(), destList);
				}	
			}
			
			if(authRelation.getAuthId() == AuthDimensionEnum.EMPLOYEE_GROUP.getId()) {
				if(resultMap.get(AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix()) == null) {
					resultMap.put(AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix(), new ArrayList<Long>(Arrays.asList(values)));
				}else {
					List<Long> sourceList = resultMap.get(AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix());
					sourceList.addAll(new ArrayList<Long>(Arrays.asList(values)));
					// 利用set去重
					Set<Long> set = new HashSet<>(sourceList);
			        List<Long> destList = new ArrayList<>(set);
			        resultMap.put(AuthDimensionEnum.EMPLOYEE_GROUP.getPrefix(), destList);
				}	
			}
		}
		resultMap.put(AuthDimensionEnum.PARENT.getPrefix(), parentList);
		
		return resultMap;
	}
	/**
	 * 在long数据前面加一个前缀
	 * @param prefix
	 * @param param
	 * @return
	 */
	private Long convertToLongParam(int prefix,Long param) {
		int length = param.toString().length();		
		Long add = (long) (Math.pow(10, (double)length) * prefix);		
		return add + param;
	}	
}
